<?php
/**
 * ===============================================
 * 版权所有 2019-2050 青岛铁锤科技有限公司，并保留所有权利。
 * 网站地址: http://www.huaxianling.com
 * ===============================================
 * Author: Rag Hu
 * Created Time: 2019/7/10 10:16
 * Modified Time: 2019/7/10 10:16
 * Version: 2.0
 */

namespace App\Modules\Inventory\Services;


use App\Exceptions\AllValidatorException;
use App\Exceptions\DbException;
use App\Lib\Auth\FLAuth;
use App\Lib\Utilities;
use App\Modules\Cashier\Repositories\BillRepository;
use App\Modules\Employee\Repositories\EmployeeRepository;
use App\Modules\Inventory\Criterias\getBarberUseGoodsRecordCriteria;
use App\Modules\Inventory\Criterias\GetGoodsInstockRecordCriteria;
use App\Modules\Inventory\Criterias\GetMyselfGoodsSaleRecordCriteria;
use App\Modules\Inventory\Criterias\GetStoreGoodsSaleRecordCriteria;
use App\Modules\Inventory\Repositories\GoodsOrderRepository;
use App\Modules\Inventory\Repositories\GoodsRepository;
use App\Modules\Inventory\Repositories\GoodsStockRepository;
use App\Modules\Inventory\Repositories\GoodsUseDetailRepository;
use App\Modules\Inventory\Repositories\GoodsUseRepository;
use App\Modules\Inventory\Repositories\InstockRepository;
use App\Modules\Inventory\Repositories\SalePurchaseRepository;
use App\Modules\Order\Repositories\RoyaltyRepository;
use App\Modules\System\Repositories\AmountFlowRepository;
use Flower\Core\Repository\Eloquent\BaseService;
use Flower\Core\Repository\Exceptions\ValidatorException;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\MessageBag;
use mysql_xdevapi\Exception;

class InstockService extends BaseService
{
	protected $goodsService;
	protected $goodsRepository;
	protected $instockRepository;
	protected $salePurchaseRepository;
	protected $goodsStockRepository;
	protected $goodsOrderRepository;
	protected $goodsUseRepository;
	protected $amountFlowRepository;
	protected $royaltyRepository;
	protected $goodsUseDetailRepository;
	protected $billRepository;
	protected $employeeRepository;
	public function __construct(InstockRepository $instockRepository,
	                            GoodsRepository $goodsRepository,
	                            GoodsStockRepository $goodsStockRepository,
	                            GoodsUseRepository $goodsUseRepository,
	                            GoodsOrderRepository $goodsOrderRepository,
	                            GoodsUseDetailRepository $goodsUseDetailRepository,
	                            GoodsService $goodsService,
	                            AmountFlowRepository $amountFlowRepository,
	                            RoyaltyRepository $royaltyRepository,
	                            SalePurchaseRepository $salePurchaseRepository,BillRepository $billRepository,EmployeeRepository $employeeRepository)
	{
		$this->goodsRepository = $goodsRepository;
		$this->instockRepository = $instockRepository;
		$this->goodsService = $goodsService;
		$this->salePurchaseRepository = $salePurchaseRepository;
		$this->goodsStockRepository = $goodsStockRepository;
		$this->goodsOrderRepository = $goodsOrderRepository;
		$this->goodsUseRepository = $goodsUseRepository;
		$this->amountFlowRepository = $amountFlowRepository;
		$this->royaltyRepository = $royaltyRepository;
		$this->goodsUseDetailRepository = $goodsUseDetailRepository;
		$this->billRepository = $billRepository;
		$this->employeeRepository = $employeeRepository;
	}

	/**
	 * 商品入库
	 * @param $store_id
	 * @param $goods_id
	 * @param $count
	 * @param $price
	 * @throws AllValidatorException
	 * @throws ValidatorException
	 */
	public function goodsInstock($store_id, $goods_id, $count, $price)
	{
		//判断商品是否存在
		$goods = $this->goodsService->checkGoodsExist($store_id, $goods_id);

		DB::beginTransaction();

		try {
			$totle = $count * $price;
			$goods_name = $goods->name;
			$this->instockRepository->createInstock($store_id, $goods_id, $goods_name, $count, $price, $totle);
			$this->salePurchaseRepository->createSalePurchase($store_id, $goods_id, $goods_name, 1, 1, $count);
			$this->goodsStockRepository->stockBuildup($goods_id, $count);

			return DB::commit();
		} catch (Exception $e) {
			DB::rollBack();
			throw new DbException();
		}
	}

	/**
	 * 获取入库记录
	 * @param Request $request
	 * @return mixed
	 * @throws AllValidatorException
	 */
	public function goodsInstockRecord($store_id, $pageSize)
	{
		$data = $this
			->instockRepository
			->pushCriteria(new GetGoodsInstockRecordCriteria($store_id))
			->paginate($pageSize, [' * ']);

		return Utilities::dealPage($data);
	}

	/**
	 * 	 * 商品销售 数据检测
	 * @param $user_id
	 * @param $store_id
	 * @param $goods_id
	 * @param $real_price
	 * @param $count
	 * @param $payment
	 * @param $remark
	 * @return array
	 * @throws AllValidatorException
	 */
	public function goodsSale($bill_id,$user_id, $store_id, $goods, $payment, $remark)
	{
		// 检测订单是否已经被支付
		$billInfo = $this->billRepository->isNotPay($bill_id);
		$order = $billInfo->goodsOrder;
		// goods_id count price barber_id assistant_id
		$goods = array_map(function ($v){

			$v['goods'] = $this->goodsRepository->checkExist($v['goods_id']);
			$stock = $this->goodsStockRepository->getGoodsStock($v['goods_id']);
			if ($stock < ($v['count'] * 100)) {
				throw new AllValidatorException(['msg' => '库存量不足']);
			}
			if(!empty($v['barber_id'])) {
				$v['barber'] = $this->employeeRepository->isExited($v['barber_id']);
			}
			if(!empty($v['assistant_id']))
			{
				$v['assist'] = $this->employeeRepository->isExited($v['assistant_id']);
			}
			return $v;
		},$goods);
		//判断库存是否充足

		return compact('goods','store_id','user_id','payment','remark','order');

	}

	/*
	 * 商品使用（领料）
	 */
	public function goodsUse($store_id, $goods_data)
	{

		$user_id = \App\Lib\Facades\FLAuth::id();

		$goods_data = json_decode($goods_data);

		if (count($goods_data) == 0) {
			throw new AllValidatorException(['msg' => '请至少选择一件商品']);
		}

		DB::beginTransaction();

		try {
			$goods_use = $this->createGoodsUse($user_id, $store_id);


			foreach ($goods_data as $key => $value) {


				$goods_id = $value->goods_id;
				$percent = $value->percent;
				$goods = $this->goodsRepository->find($goods_id);

				//判断库存是否充足
				$goods_stock = $this->checkStock($goods_id, $percent);

				//插入使用详情表
				$this->createGoodsUseDetail($goods_use, $goods_id, $percent);

				if ($goods_stock->prev_percent + $percent >= 100) { //用了一瓶以上

					//计算使用数量
					$num = floor(($goods_stock->prev_percent + $percent) / 100);
					$goods_stock->update([
						'percent'      => $goods_stock->percent - $percent,
						'prev_percent' => ($goods_stock->prev_percent + $percent) % 100,
						'count'        => $goods_stock->count - $num
					]);

					//插入进销记录表
					$this->createGoodsSale($store_id, $goods_id, $goods, $num);


				} else { //没用完一瓶
					$goods_stock->update([
						'percent'      => $goods_stock->percent - $percent,
						'prev_percent' => $goods_stock->prev_percent + $percent
					]);
				}
			}
			DB::commit();
		} catch (Exception $e) {
			DB::rollBack();
			throw new DbException();
		}
	}

	/*
	 * 店长获取理发师领料记录
	 */
	public function getBarberUseGoodsRecord($store_id, $pageSize)
	{


		$record = $this
			->goodsUseRepository
			->pushCriteria(new getBarberUseGoodsRecordCriteria($store_id))
			->paginate($pageSize, [' * ']);

		return Utilities::dealPage($record);
	}

	/*
	 * 理发师获取本人在某店领料记录
	 */
	public function getMyselfUseGoodsRecord($store_id, $user_id, $pageSize)
	{


		$record = $this
			->goodsUseRepository
			->pushCriteria(new getBarberUseGoodsRecordCriteria($store_id, $user_id))
			->paginate($pageSize, [' * ']);


		return Utilities::dealPage($record);
	}

	/*
	 * 获取店铺销售记录
	 */
	public function getStoreGoodsSaleRecord($store_id, $pageSize)
	{
		$data = $this
			->goodsOrderRepository
			->pushCriteria(new GetStoreGoodsSaleRecordCriteria($store_id))
			->paginate($pageSize, [' * ']);

		return Utilities::dealPage($data);
	}

	/*
	 * 获取本人销售记录
	 */
	public function getMyselfGoodsSaleRecord($store_id, $pageSize)
	{
		$user_id = \App\Lib\Facades\FLAuth::id();
		$data = $this
			->goodsOrderRepository
			->pushCriteria(new GetMyselfGoodsSaleRecordCriteria($store_id, $user_id))
			->paginate($pageSize, [' * ']);

		return Utilities::dealPage($data);
	}

	/*
	 * 创建商品使用主表 goods_use
	 */
	protected function createGoodsUse($user_id, $store_id)
	{
		$goods_use_data = [
			'user_id'  => $user_id,
			'store_id' => $store_id
		];
		return $this->goodsUseRepository->create($goods_use_data);
	}

	/*
	 * 判断库存是否充足
	 */
	protected function checkStock($goods_id, $percent)
	{
		$goods_stock = $this
			->goodsStockRepository
			->find($goods_id);
		$now_percent = $goods_stock->prev_percent + $goods_stock->percent;

		if ($now_percent < $percent) {
			throw new AllValidatorException(['msg' => '库存不足']);
		}

		return $goods_stock;
	}

	/*
	 * 插入使用详情表
	 */
	protected function createGoodsUseDetail($goods_use, $goods_id, $percent)
	{
		//插入使用详情表
		$goods_use_detail_data = [
			'use_id'   => $goods_use->id,
			'goods_id' => $goods_id,
			'percent'  => $percent
		];

		$this->goodsUseDetailRepository->create($goods_use_detail_data);

	}

	/*
	 * 插入进销记录表
	 */
	protected function createGoodsSale($store_id, $goods_id, $goods, $num)
	{
		$goods_sale_data = [
			'store_id'   => $store_id,
			'goods_id'   => $goods_id,
			'goods_name' => $goods->name,
			'type'       => 2,
			'source'     => 3,
			'count'      => -$num,

		];
		$this->salePurchaseRepository->create($goods_sale_data);

	}

}